﻿using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using System.Drawing.Text;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Serilog;
using Serilog.Extensions.Logging;
using Serilog.Events;
using Serilog.Sinks.SystemConsole;
using SIPSorcery.SIP;
using SIPSorcery.SIP.App;
using SIPSorcery.Media;
using SIPSorcery.Net;
using SIPSorceryMedia.Abstractions;
using SIPSorceryMedia.Windows;
using System.Runtime.Intrinsics.Arm;
using System.Text;
using System.Security.Cryptography;
using Windows.Devices.PointOfService;
using static iTextSharp.text.pdf.PdfDocument;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
using System.DirectoryServices.ActiveDirectory;

namespace Agent
{
    public struct ACDCall
    {
        public SIPServerUserAgent uas;
        public string remoteUser;
        public string message;
        public string localTag;
    }

    public struct ACDAgent
    {
        public string number;
        public string lastCall1;
        public string lastCall2;
        public string lastCall3;
    }

    public struct ACDSession
    {
        public string agentNumber;
        public string remoteNumber;
        public string message;
        public string localTag;
    }

    public class SIP
    {
        #region 常量
        private const int DEFAULT_EXPIRY = 120;                                   // 注册有效期
        private const string DEFAULT_SIPS_SERVER_CERTIFICATE_PATH = "server.crt"; // 证书路径
        private const string DEFAULT_SIPS_PRIVATE_KEY_PATH = "server.key";        // 私钥路径
        private const int DEFAULT_MAX_ACD_CALLS = 20;                             // ACD队列最大长度
        private const int DEFAULT_MAX_IDLE_AGENTS = 20;                          // 空闲坐席队列最大长度
        #endregion

        #region 变量
        //SIP状态
        public bool isStartUp = false;// 是否启用
        public bool isRegister = false;// 是否注册
        public bool isReceiveMsg = false;// 是否接收消息
        public bool isListen = false;// 是否监听
        /* 通话状态:未注册_Unregistered|空闲_Free|挂断_Bye|通话结束_End
         * 主动呼叫_Invite|主动呼叫_Ringing|主动呼叫_Talking
         * 主动呼叫_Cancel|主动呼叫_Busy|主动呼叫_Decline|主动呼叫_Failed
         * 被呼叫_Ringing|被呼叫_Cancel|被呼叫_Decline|被呼叫_Accept|被呼叫_Talking */
        private string status = "";

        // 参数_本机信息
        private string user = "";     //用户名
        private string password = ""; // 密码

        //  参数_服务器信息
        private SIPEndPoint? outboundProxy;     // 实际使用的服务器地址、端口、传输协议
        private string sipServerIp = "";        // SIP服务器IP地址
        private int sipServerPort = -1;         // SIP服务器端口
        private int sipServerTlsPort = -1;      // SIP服务器TLS端口
        private string sipServerTransport = ""; // SIP服务器传输协议
        private string sipProxyIp = "";         // SIP代理IP地址
        private int sipProxyPort = -1;          // SIP代理端口
        private int sipProxyTlsPort = -1;       // SIP代理TLS端口
        private string sipProxyTransport = "";  // SIP代理传输协议
        private int expiry = -1;                // 注册有效期
        private string sipSignUpUrl = "";       // 账号注册页面URL

        // 参数_会话信息
        private string remoteUser = "";         // 对方用户名
        private string userOption = "";         // 用户选项(Cancel|Bye|Accept|Decline|Transfer)
        bool isCallHungup = false;              // 主动呼叫_是否挂断通话
        bool hasCallFailed = false;              // 主动呼叫_是否呼叫失败

        // SIP 对象
        private SIPTransport? sipTransport;     // SIP传输层
        private SIPRegistrationUserAgent? uar;  // SIP注册用户代理
        private SIPUserAgent? ua;               // SIP用户代理
        private SIPClientUserAgent? uac;        // SIP客户端用户代理
        private SIPServerUserAgent? uas;        // SIP服务器端用户代理
        public ACDCall[] acdCalls = new ACDCall[DEFAULT_MAX_ACD_CALLS];     // ACD队列
        public int acdCallsCount = 0;                                      // ACD队列长度
        public ACDAgent[] idleAgents = new ACDAgent[DEFAULT_MAX_IDLE_AGENTS];  // 空闲坐席队列
        public int idleAgentsCount = 0;                                     // 空闲坐席队列长度

        // 媒体对象
        private VoIPMediaSession? rtpSession;   // RTP会话

        // 事件(用于同步操作)
        private ManualResetEvent userOptionMre = new ManualResetEvent(false);   // 用户选项选择事件
        private ManualResetEvent hungupMre = new ManualResetEvent(false);       // 挂断事件
        private ManualResetEvent stopListenMre = new ManualResetEvent(false);   // 停止监听事件
        #endregion

        #region public方法
        /// <summary>
        /// 没用的空构造函数
        /// </summary>
        public SIP()
        {

        }

        /// <summary>
        /// 获取状态
        /// </summary>
        public string GetStatus()
        {
            return status;
        }

        /// <summary>
        /// 获取通话对方用户名
        /// </summary>
        public string GetRemoteUser()
        {
            return remoteUser;
        }

        /// <summary>
        /// 设置通话对方用户名
        /// </summary>
        public void SetRemoteUser(string remoteUser)
        {
            this.remoteUser = remoteUser;
            if (remoteUser == "") status = "空闲_Free";
            else status = "占用_Busy";
        }

        /// <summary>
        /// 用户选项选择
        /// </summary>
        public void UserOptionSelect(string option)
        {
            userOption = option;
            userOptionMre.Set();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void StartUp(string user, string password,
             string sipServerUri, string sipProxyUri = "", int expiry = DEFAULT_EXPIRY,
             string sipSignUpUrl = "")
        {
            /* 检查参数格式
             * sipServerUri的格式为sipServerIP[:sipServerPort][;transport=transport]
             * transport=transport的格式为[udp|tcp|tls]
             * sipProxyUri的格式为sipProxyIP[:sipProxyPort][;transport=transport]
             * transport=transport的格式为[udp|tcp|tls]
             * expiry的格式为整数,默认值为120 */
            if (user == "")
            {
                MessageBox.Show("用户名不能为空");
                return;
            }
            else if (sipServerUri == "")
            {
                MessageBox.Show("SIP服务器地址不能为空");
                return;
            }

            // 必要条件检查
            if (isStartUp)
            {
                MessageBox.Show("已经初始化过了");
                return;
            }

            // 设置参数
            this.user = user;
            this.password = password;
            sipServerIp = sipServerUri.Split(':')[0];
            if (sipServerUri.Contains(";transport="))
            {
                sipServerTransport = sipServerUri.Split(';')[1].Split('=')[1];
            }
            else
            {
                sipServerTransport = "udp";
            }
            if (sipServerUri.Contains(":"))
            {
                if (sipServerTransport == "tls")
                {
                    sipServerPort = 5060;
                    sipServerTlsPort = int.Parse(sipServerUri.Split(':')[1].Split(';')[0]);
                }
                else
                {
                    sipServerPort = int.Parse(sipServerUri.Split(':')[1].Split(';')[0]);
                    sipServerTlsPort = 5061;
                }
            }
            else
            {
                sipServerPort = 5060;
                sipServerTlsPort = 5061;
            }
            if (sipProxyUri != "")
            {
                sipProxyIp = sipProxyUri.Split(':')[0];
                if (sipProxyUri.Contains(";transport="))
                {
                    sipProxyTransport = sipProxyUri.Split(';')[1].Split('=')[1];
                }
                else
                {
                    sipProxyTransport = "udp";
                }
                if (sipProxyUri.Contains(":"))
                {
                    if (sipProxyTransport == "tls")
                    {
                        sipProxyPort = 5060;
                        sipProxyTlsPort = int.Parse(sipProxyUri.Split(':')[1].Split(';')[0]);
                    }
                    else
                    {
                        sipProxyPort = int.Parse(sipProxyUri.Split(':')[1].Split(';')[0]);
                        sipProxyTlsPort = 5061;
                    }
                }
                else
                {
                    sipProxyPort = 5060;
                    sipProxyTlsPort = 5061;
                }
            }
            this.sipSignUpUrl = sipSignUpUrl;
            this.expiry = expiry;
            remoteUser = "";
            userOption = "";

            // 设置outboundProxy
            if (sipProxyUri != "")
            {
                switch (sipProxyTransport)
                {
                    case "udp":
                        outboundProxy = new SIPEndPoint(SIPProtocolsEnum.udp, IPAddress.Parse(sipProxyIp), sipProxyPort);
                        break;
                    case "tcp":
                        outboundProxy = new SIPEndPoint(SIPProtocolsEnum.tcp, IPAddress.Parse(sipProxyIp), sipProxyPort);
                        break;
                    case "tls":
                        outboundProxy = new SIPEndPoint(SIPProtocolsEnum.tls, IPAddress.Parse(sipProxyIp), sipProxyTlsPort);
                        break;
                    default:
                        break;
                }
            }
            else
            {
                switch (sipServerTransport)
                {
                    case "udp":
                        outboundProxy = new SIPEndPoint(SIPProtocolsEnum.udp, IPAddress.Parse(sipServerIp), sipServerPort);
                        break;
                    case "tcp":
                        outboundProxy = new SIPEndPoint(SIPProtocolsEnum.tcp, IPAddress.Parse(sipServerIp), sipServerPort);
                        break;
                    case "tls":
                        outboundProxy = new SIPEndPoint(SIPProtocolsEnum.tls, IPAddress.Parse(sipServerIp), sipServerTlsPort);
                        break;
                    default:
                        break;
                }
            }
            if (outboundProxy == null)
            {
                outboundProxy = new SIPEndPoint(SIPProtocolsEnum.udp, IPAddress.Parse(sipServerIp), sipServerPort);
            }

            // 加载证书
            string certPem = File.ReadAllText(DEFAULT_SIPS_SERVER_CERTIFICATE_PATH, Encoding.UTF8);
            string keyPem = File.ReadAllText(DEFAULT_SIPS_PRIVATE_KEY_PATH, Encoding.UTF8);
            var serverCertificate = X509Certificate2.CreateFromPem(certPem, keyPem);

            // 初始化SIP传输层
            sipTransport = new SIPTransport();
            sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.Any, 0)));
            sipTransport.AddSIPChannel(new SIPTCPChannel(new IPEndPoint(IPAddress.Any, 0)));
            sipTransport.AddSIPChannel(new SIPTLSChannel(serverCertificate, new IPEndPoint(IPAddress.Any, 0), false));

            // 重置MRE
            userOptionMre.Reset();
            hungupMre.Reset();
            stopListenMre.Reset();

            //设置状态
            isStartUp = true;
            status = "未注册_Unregistered";
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        public void CleanUp()
        {
            // 挂断当前通话,清除所有用户代理
            if (status != "空闲_Free" && status != "未注册_Unregistered")
            {
                UserOptionSelect("Bye");
                Thread.Sleep(1000);
                stopListenMre.Set();
            }
            if (isReceiveMsg) StopReceiveMsg();

            // 注销
            if (isRegister) UnRegister();

            // 关闭SIP传输层
            if (sipTransport != null)
            {
                sipTransport.Shutdown();
                while (sipTransport.GetSIPChannels().Count > 0)
                {
                    sipTransport.RemoveSIPChannel(sipTransport.GetSIPChannels().First());
                }
                sipTransport = null;
            }

            // 清除参数
            user = "";
            password = "";
            outboundProxy = null;
            sipServerIp = "";
            sipServerPort = -1;
            sipServerTlsPort = -1;
            sipServerTransport = "";
            sipProxyIp = "";
            sipProxyPort = -1;
            sipProxyTlsPort = -1;
            sipProxyTransport = "";
            expiry = -1;
            sipSignUpUrl = "";
            remoteUser = "";
            userOption = "";

            // 重置状态
            isStartUp = false;
        }

        /// <summary>
        /// 注册
        /// </summary>
        public void Register()
        {
            // 必要条件检查
            if (!isStartUp || outboundProxy == null)
            {
                MessageBox.Show("请先初始化");
                return;
            }
            if (isRegister)
            {
                MessageBox.Show("已经注册过了");
                return;
            }

            // 初始化注册用户代理
            uar = new SIPRegistrationUserAgent(sipTransport, user, password,
                outboundProxy.Address.ToString(), expiry);

            // 设置代理服务器并选择模式
            uar.OutboundProxy = outboundProxy;


            // 注册成功时设置状态
            uar.RegistrationSuccessful += (uri, resp) =>
            {
                isRegister = true;
                status = "空闲_Free";
                OnRegisterSuccess();
            };

            // 注册失败时提示并注销
            uar.RegistrationFailed += (uri, resp, str) =>
            {
                MessageBox.Show("注册失败：" + str);
                UnRegister();
            };

            uar.RegistrationTemporaryFailure += (uri, resp, str) =>
            {
                MessageBox.Show("注册失败：" + str);
                UnRegister();
            };

            // 运行注册线程
            uar.Start();
        }

        /// <summary>
        /// 注销
        /// </summary>
        public void UnRegister()
        {
            if (status != "空闲_Free" && status != "未注册_Unregistered")
            {
                MessageBox.Show("当前状态不允许注销");
                return;
            }

            // 注销
            if (uar != null)
            {
                // 注销成功事件
                uar.RegistrationRemoved += (uri, resp) =>
                {
                    OnUnRegisterSuccess();
                };

                // 注销
                uar.Stop();
                Thread.Sleep(1000);
                uar = null;
            }

            // 重置状态
            isRegister = false;
            status = "未注册_Unregistered";
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        public void SendMsg(string remoteUser, string msg)
        {
            // 必要条件检查
            if (sipTransport == null || outboundProxy == null)
            {
                MessageBox.Show("请先初始化");
                return;
            }
            if (isRegister == false)
            {
                MessageBox.Show("请先注册");
                return;
            }

            // 生成目标URI
            string callUri = "sip:" + remoteUser + "@" + outboundProxy.Address;

            // 生成From_URI
            string callBackNumber = "sip:" + user + "@" + outboundProxy.Address;

            // 生成呼叫描述符
            SIPCallDescriptor callDescriptor = new SIPCallDescriptor(
                user,                       // 用户名
                password,                   // 密码
                callUri,                    // 目标URI
                callBackNumber,             // From_URI
                callUri,                    // To_URI,可与目标URI相同或为空
                null,                       // 路由
                null,                       // 自定义消息头
                user,                       // 授权用户名
                SIPCallDirection.Out,       // 呼叫方向
                "text/plain",               // 内容类型
                msg,                        // 内容
                null                        // mangleIPAddress
            );

            // 发送MESSAGE报文
            SIPNonInviteClientUserAgent uanc = new SIPNonInviteClientUserAgent(sipTransport, outboundProxy, callDescriptor);
            uanc.SendRequest(SIPMethodsEnum.MESSAGE);
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        public void ReceiveMsg()
        {
            // 必要条件检查
            if (!isRegister || sipTransport == null)
            {
                MessageBox.Show("请先注册！");
                return;
            }
            if (isReceiveMsg)
            {
                MessageBox.Show("已经在接收消息了");
                return;
            }

            isReceiveMsg = true;
            sipTransport.SIPTransportRequestReceived += SIPReceiveMsg;
        }

        /// <summary>
        /// 停止接收消息
        /// </summary>
        public void StopReceiveMsg()
        {
            // 必要条件检查
            if (!isRegister || sipTransport == null)
            {
                MessageBox.Show("当前状态不允许停止接收消息");
                return;
            }

            if (isReceiveMsg)
            {
                sipTransport.SIPTransportRequestReceived -= SIPReceiveMsg;
                isReceiveMsg = false;
            }
        }

        /// <summary>
        /// 呼叫
        /// </summary>
        public void Call(string RemoteUser, string message)
        {
            // 必要条件检查
            if (sipTransport == null || outboundProxy == null)
            {
                MessageBox.Show("请先初始化");
                return;
            }
            if (isRegister == false)
            {
                MessageBox.Show("请先注册");
                return;
            }
            if (status != "空闲_Free")
            {
                MessageBox.Show("当前状态不允许呼叫");
                return;
            }

            // 初始化会话信息
            remoteUser = RemoteUser;                            // 设置对方用户名
            bool preferIPv6 = false;                            // 选择是否优先使用IPv6
            sipTransport.PreferIPv6NameResolution = preferIPv6; // 设置是否优先使用IPv6
            hungupMre.Reset();                                  // 重置挂断事件

            // 设置局部呼叫状态标记
            isCallHungup = false;                               // 是否已挂断
            hasCallFailed = false;                              // 是否呼叫失败

            // 创建管理会话的类和媒体类的实例
            uac = new SIPClientUserAgent(sipTransport, outboundProxy);            // SIP客户端用户代理
            var audioSession = new WindowsAudioEndPoint(new AudioEncoder());      // 音频输出设备
            rtpSession = new VoIPMediaSession(audioSession.ToMediaEndPoints());   // RTP会话
            rtpSession.AcceptRtpFromAny = true;                                   // 允许任何来源的RTP流

            // 准备呼叫需要的SDP
            var offerSDP = rtpSession.CreateOffer(preferIPv6 ? IPAddress.IPv6Any : IPAddress.Any);  // 创建SDP
            if (message != "")
            {
                // message中可能有多项，由|符号分隔，分割开后添加到SDP中
                string[] messages = message.Split('|');
                foreach (string m in messages)
                {
                    offerSDP.AddExtra("a=" + m + ";");
                }
            }

            // 生成目标URI
            string callUri = "sip:" + remoteUser + "@" + outboundProxy.Address;

            // 生成From_URI
            string callBackNumber = "sip:" + user + "@" + outboundProxy.Address;

            // 生成呼叫描述符
            SIPCallDescriptor callDescriptor = new SIPCallDescriptor(
                user,                       // 用户名
                password,                   // 密码
                callUri,                    // 目标URI
                callBackNumber,             // From地址URI
                callUri,                    // To地址URI,可与目标URI相同或为空
                null,                       // 路由
                null,                       // 自定义消息头
                user,                       // 授权用户名
                SIPCallDirection.Out,       // 呼叫方向
                SDP.SDP_MIME_CONTENTTYPE,   // 内容类型
                offerSDP.ToString(),        // 内容
                null                        // mangleIPAddress
            );

            #region 订阅呼叫状态事件
            // 订阅对方振铃事件,尝试开启RTP会话
            uac.CallRinging += async (uac, resp) =>
            {
                status = "主动呼叫_Ringing";
                OnActiveRinging();

                if (resp.Status == SIPResponseStatusCodesEnum.SessionProgress)
                {
                    if (resp.Body != null)
                    {
                        var result = rtpSession.SetRemoteDescription(SdpType.answer, SDP.ParseSDPDescription(resp.Body));
                        if (result == SetDescriptionResultEnum.OK)
                        {
                            await rtpSession.Start();
                        }
                    }
                }
            };

            // 呼叫失败时,设置状态并退出
            uac.CallFailed += (uac, err, resp) =>
            {
                status = "主动呼叫_Failed";
                OnActiveFailed();

                hasCallFailed = true;
                hungupMre.Set();
            };

            // 收到响应
            uac.CallAnswered += async (iuac, resp) =>
            {
                // 收到BusyHere
                if (resp.Status == SIPResponseStatusCodesEnum.BusyHere)
                {
                    status = "主动呼叫_Busy";
                    OnActiveBusy();

                    hasCallFailed = true;
                    hungupMre.Set();
                    return;
                }
                // 收到Decline
                else if (resp.Status == SIPResponseStatusCodesEnum.Decline)
                {
                    status = "主动呼叫_Decline";
                    OnActiveDecline();

                    hasCallFailed = true;
                    hungupMre.Set();
                    return;
                }
                // 收到TemporarilyUnavailable
                else if (resp.Status == SIPResponseStatusCodesEnum.TemporarilyUnavailable)
                {
                    status = "主动呼叫_Failed";
                    OnActiveFailed();

                    hasCallFailed = true;
                    hungupMre.Set();
                    return;
                }
                // 收到Not Found
                else if (resp.Status == SIPResponseStatusCodesEnum.NotFound)
                {
                    status = "主动呼叫_Failed";
                    OnActiveFailed();

                    hasCallFailed = true;
                    hungupMre.Set();
                    return;
                }
                // 收到200 OK
                else if (resp.Status == SIPResponseStatusCodesEnum.Ok)
                {
                    // 回复ACK请求
                    SIPRequest ackRequest = SIPRequest.GetRequest(SIPMethodsEnum.ACK, SIPURI.ParseSIPURI(callUri));
                    await sipTransport.SendRequestAsync(ackRequest);

                    // 检查是否获得了SDP
                    if (resp.Body == null && !rtpSession.IsStarted)
                    {
                        status = "主动呼叫_Failed";
                        OnActiveFailed();
                        hungupMre.Set();
                    }
                    else if (resp.Body == null && rtpSession.IsStarted)
                    {
                        status = "主动呼叫_Talking";
                        OnActiveTalking();
                    }
                    else
                    {
                        var result = rtpSession.SetRemoteDescription(SdpType.answer, SDP.ParseSDPDescription(resp.Body));
                        if (result == SetDescriptionResultEnum.OK)
                        {
                            await rtpSession.Start();
                            status = "主动呼叫_Talking";
                            OnActiveTalking();
                        }
                        else
                        {
                            status = "主动呼叫_Failed";
                            OnActiveFailed();
                            hungupMre.Set();
                        }
                    }
                }
                else
                {
                    MessageBox.Show("收到未知响应：" + resp.Status + " " + resp.ReasonPhrase);
                }
            };

            // 收到BYE报文
            sipTransport.SIPTransportRequestReceived += SIPReceiveBye;
            #endregion

            // 监测用户操作
            Task.Run(() =>
            {
                userOption = "";                                    // 清空用户选项
                userOptionMre.Reset();                              // 重置用户选项选择事件

                while (true)
                {
                    userOptionMre.WaitOne();

                    if (hungupMre.WaitOne(0)) break;

                    if (userOption == "Cancel")
                    {
                        status = "主动呼叫_Cancel";
                        OnActiveCancel();

                        hungupMre.Set();
                        break;
                    }
                    else if (userOption == "Bye")
                    {
                        status = "挂断_Bye";
                        OnBye();

                        hungupMre.Set();
                        break;
                    }

                    userOption = "";
                    userOptionMre.Reset();
                }
            });

            // 设置状态,发送INVITE请求
            status = "主动呼叫_Invite";
            OnActiveInvite();
            uac.Call(callDescriptor);

            // 等待挂断事件
            hungupMre.WaitOne();                                        // 等待挂断事件

            // 清理资源
            sipTransport.SIPTransportRequestReceived -= SIPReceiveBye;  // 注销BYE监听
            userOptionMre.Set();                                        // 停止检测用户操作
            rtpSession.Close(null);                                     // 关闭RTP会话

            // 发送BYE或CANCEL请求
            if (!isCallHungup && uac != null)
            {
                if (uac.IsUACAnswered)
                {
                    uac.Hangup();
                }
                else if (!hasCallFailed)
                {
                    uac.Cancel();
                }
            }

            // 清理资源,重置状态
            isCallHungup = false;
            hasCallFailed = false;
            hungupMre.Reset();
            uac = null;
            rtpSession = null;
            remoteUser = "";
            status = "空闲_Free";
            OnEnd();
        }

        /// <summary>
        /// 监听
        /// </summary>
        public void Listen()
        {
            // 必要条件检查
            if (sipTransport == null || isStartUp == false || isRegister == false)
            {
                MessageBox.Show("请先初始化/注册");
                return;
            }
            if (isListen)
            {
                MessageBox.Show("已经在监听了");
                return;
            }
            isListen = true;

            // 创建管理会话的类的实例
            uas = null;
            VoIPMediaSession? rtpSession = null;
            stopListenMre.Reset();

            // 订阅收到请求报文事件
            sipTransport.SIPTransportRequestReceived += SIPReceiveRequest;

            // 等待退出事件
            stopListenMre.WaitOne();
            stopListenMre.Reset();

            // 挂断正在通话的呼叫,清理资源
            sipTransport.SIPTransportRequestReceived -= SIPReceiveRequest;
            if (uas != null && !uas.IsHungup) uas.Hangup(false);
            rtpSession?.Close(null);
            hungupMre.Set();
            userOptionMre.Set();
            isListen = false;
        }

        /// <summary>
        /// ACD监听
        /// </summary>
        public void ACDListen()
        {
            // 必要条件检查
            if (sipTransport == null || isStartUp == false || isRegister == false)
            {
                MessageBox.Show("请先初始化/注册");
                return;
            }
            if (isListen)
            {
                MessageBox.Show("已经在监听了");
                return;
            }
            isListen = true;

            sipTransport.SIPTransportRequestReceived += SIPACD;

            stopListenMre.WaitOne();
            stopListenMre.Reset();

            // 挂断正在排队的呼叫,清理资源
            sipTransport.SIPTransportRequestReceived -= SIPACD;
            for (int i = 0; i < acdCallsCount; i++)
            {
                if (acdCalls[i].uas != null && !acdCalls[i].uas.IsHungup) acdCalls[i].uas.Hangup(false);
                acdCalls[i].remoteUser = "";
                acdCalls[i].message = "";
            }
            isListen = false;
            acdCallsCount = 0;
            OnACDListChanged();
        }

        /// <summary>
        /// 添加空闲坐席
        /// </summary>
        public void AddFreeAgent(string number, string lastCall1, string lastCall2, string lastCall3)
        {

            if (idleAgentsCount >= DEFAULT_MAX_IDLE_AGENTS)
            {
                MessageBox.Show("空闲坐席队列已满");
                return;
            }

            idleAgents[idleAgentsCount].number = number;
            idleAgents[idleAgentsCount].lastCall1 = lastCall1;
            idleAgents[idleAgentsCount].lastCall2 = lastCall2;
            idleAgents[idleAgentsCount].lastCall3 = lastCall3;
            idleAgentsCount++;

            if (acdCallsCount == 0) return; // 如果没有排队的呼叫，则不用分配

            // 分配呼叫
            if (outboundProxy == null) return;

            // 呼叫转移
            SIPURI redirectURI = SIPURI.ParseSIPURI("sip:" + number + "@" + outboundProxy.Address);
            acdCalls[0].uas.Redirect(SIPResponseStatusCodesEnum.MovedPermanently, redirectURI);

            ACDSession acdSession = new ACDSession();
            acdSession.agentNumber = number;
            acdSession.remoteNumber = acdCalls[0].remoteUser;
            acdSession.message = acdCalls[0].message;
            acdSession.localTag = acdCalls[0].localTag;
            OnACDAllocateSuccess(acdSession);

            // 释放空闲坐席
            for (int i = 0; i < idleAgentsCount; i++)
            {
                if (idleAgents[i].number == number)
                {
                    for (int j = i; j < idleAgentsCount - 1; j++)
                    {
                        idleAgents[j] = idleAgents[j + 1];
                    }
                    idleAgentsCount--;
                    break;
                }
            }
            // 释放排队呼叫
            for (int i = 0; i < acdCallsCount; i++)
            {
                acdCalls[i] = acdCalls[i + 1];
            }
            acdCallsCount--;
            OnACDListChanged();
        }

        /// <summary>
        /// 移除坐席
        /// </summary>
        public void RemoveAgent(string number)
        {
            for (int i = 0; i < idleAgentsCount; i++)
            {
                if (idleAgents[i].number == number)
                {
                    for (int j = i; j < idleAgentsCount - 1; j++)
                    {
                        idleAgents[j] = idleAgents[j + 1];
                    }
                    idleAgentsCount--;
                    break;
                }
            }
        }
        #endregion

        #region private方法
        /// <summary>
        /// 接收到MESSAGE报文
        /// </summary>
        private async Task SIPReceiveMsg(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            // 处理MESSAGE报文
            if (sipRequest.Method == SIPMethodsEnum.MESSAGE)
            {
                if (sipTransport != null)
                {
                    //回复 200 OK
                    SIPResponse okResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                    await sipTransport.SendResponseAsync(okResponse);
                }

                OnReceiveMsg(sipRequest);
            }
        }

        /// <summary>
        /// 主动呼叫处理BYE报文
        /// </summary>
        private async Task SIPReceiveBye(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            if (sipRequest.Method == SIPMethodsEnum.BYE)
            {
                status = "挂断_Bye";
                OnBye();

                // 发送200 OK响应
                SIPResponse okResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(okResponse);

                // 退出
                if (uac != null && uac.IsUACAnswered)
                {
                    isCallHungup = true;
                    hungupMre.Set();
                }
            }
        }

        /// <summary>
        /// 被呼叫处理请求报文
        /// </summary>
        private async Task SIPReceiveRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            // 处理INVITE in-dialogue请求
            if (sipRequest.Method == SIPMethodsEnum.INVITE && sipRequest.Header.To.ToTag != null)
            {
                // 回复488 Not Acceptable Here响应
                SIPResponse notAcceptableResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotAcceptable, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(notAcceptableResponse);
            }
            // 处理SUBSCRIBE请求
            else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE)
            {
                // 回复405 Method Not Allowed响应
                SIPResponse methodNotAllowedResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(methodNotAllowedResponse);
            }
            // 处理OPTIONS和REGISTER请求
            else if (sipRequest.Method == SIPMethodsEnum.OPTIONS || sipRequest.Method == SIPMethodsEnum.REGISTER)
            {
                // 回复 200 OK
                SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(optionsResponse);
            }
            // 收到BYE请求
            else if (sipRequest.Method == SIPMethodsEnum.BYE)
            {
                if (sipRequest.Header.CallId != uas?.SIPDialogue.CallId) return;

                // 回复 200 OK
                SIPResponse byeResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(byeResponse);

                // 清理资源,重置状态
                status = "挂断_Bye";
                OnBye();

                isCallHungup = true;
                hungupMre.Set();
                userOptionMre.Set();
            }
            // 收到INVITE请求
            else if (sipRequest.Method == SIPMethodsEnum.INVITE)
            {
                // 解析SDP
                var offerSDP = SDP.ParseSDPDescription(sipRequest.Body);

                // 如果已有呼叫正在进行，挂断当前的INVITE
                if (status != "空闲_Free")
                {
                    uas?.Hangup(false);
                    return;
                }

                // 检查SDP中是否包含支持的音频编解码器
                if (!offerSDP.Media.Any(x => x.Media == SDPMediaTypesEnum.audio && x.MediaFormats.Any(x => x.Key == (int)SDPWellKnownMediaFormatsEnum.PCMU)))
                {
                    return;
                }

                // 创建媒体类的实例
                var audioSession = new WindowsAudioEndPoint(new AudioEncoder());
                rtpSession = new VoIPMediaSession(audioSession.ToMediaEndPoints());
                rtpSession.AcceptRtpFromAny = true;
                var setResult = rtpSession.SetRemoteDescription(SdpType.offer, offerSDP);

                // 设置远程描述符失败时退出
                if (setResult != SetDescriptionResultEnum.OK)
                {
                    // 回复 488 Not Acceptable Here响应
                    SIPResponse noMatchingCodecResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotAcceptableHere, setResult.ToString());
                    if (sipTransport != null) await sipTransport.SendResponseAsync(noMatchingCodecResponse);

                    rtpSession?.Close(null);
                    rtpSession = null;
                    return;
                }

                // 创建管理会话的类的实例
                UASInviteTransaction uasTransaction = new UASInviteTransaction(sipTransport, sipRequest, null);
                uas = new SIPServerUserAgent(sipTransport, outboundProxy, uasTransaction, null);

                #region 订阅呼叫状态事件
                // 呼叫被取消
                uas.CallCancelled += (uasAgent, canelReq) =>
                {
                    status = "被呼叫_Cancel";
                    OnPassiveCancel();

                    isCallHungup = true;
                    hungupMre.Set();
                    userOptionMre.Set();
                };

                // 事件：RTP会话关闭
                rtpSession.OnRtpClosed += (reason) =>
                {
                    status = "挂断_Bye";
                    OnBye();

                    hungupMre.Set();
                    userOptionMre.Set();
                };
                #endregion

                // 回复 100 Trying响应
                SIPResponse tryingResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(tryingResponse);

                // 初始化会话信息
                remoteUser = sipRequest.Header.From.FromURI.User;
                isCallHungup = false;
                hungupMre.Reset();
                userOption = "";
                userOptionMre.Reset();

                // 提取消息
                if (sipRequest.Body.ToString().Contains("flag:"))
                {
                    string body = sipRequest.Body.ToString();
                    string msg = "";
                    while (body.Contains("Message="))
                    {
                        msg += body.Split("Message=")[1].Split(';')[0]+";";
                        body = body.Substring(body.IndexOf("Message=") + 8);
                    }
                    OnGetMsgFromInvite(msg);
                }

                // 回复 180 Ringing响应
                SIPResponse ringingResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ringing, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(ringingResponse);
                status = "被呼叫_Ringing";
                OnPassiveRinging();

                // 监测用户操作
                await Task.Run(() =>
                {
                    while (true)
                    {
                        userOptionMre.WaitOne();

                        if (hungupMre.WaitOne(0)) break;

                        // 用户拒接
                        if (userOption == "Decline")
                        {
                            status = "被呼叫_Decline";
                            OnPassiveDecline();

                            // 发送486 Busy Here响应
                            SIPResponse busyHereResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BusyHere, null);
                            sipTransport?.SendResponseAsync(busyHereResponse);

                            // 清理资源,重置状态
                            isCallHungup = true;
                            break;
                        }
                        // 用户接听
                        else if (userOption == "Accept")
                        {
                            status = "被呼叫_Accept";
                            OnPassiveAccept();

                            // 回复 200 OK响应
                            var answerSDP = rtpSession?.CreateAnswer(null);
                            uas.Answer(SDP.SDP_MIME_CONTENTTYPE, answerSDP?.ToString(), null, SIPDialogueTransferModesEnum.NotAllowed);
                            Thread.Sleep(100);

                            rtpSession?.Start();

                            status = "被呼叫_Talking";
                            OnPassiveTalking();
                        }
                        // 用户挂断
                        else if (userOption == "Bye")
                        {
                            status = "挂断_Bye";
                            OnBye();

                            break;
                        }
                        // 呼叫转移
                        else if (userOption.Contains("Transfer:"))
                        {
                            if (outboundProxy == null) continue;

                            string number = userOption.Substring(9);
                            SIPURI redirectURI = SIPURI.ParseSIPURI("sip:" + number + "@" + outboundProxy.Address);
                            uas.Redirect(SIPResponseStatusCodesEnum.MovedTemporarily, redirectURI);

                            isCallHungup = true;
                            break;
                        }


                        userOption = "";
                        userOptionMre.Reset();
                    }

                    if (isCallHungup)
                    {
                        uas.Hangup(true);
                    }
                    else
                    {
                        uas.Hangup(false);
                    }
                    rtpSession?.Close(null);

                    remoteUser = "";

                    status = "空闲_Free";
                    OnEnd();
                });
            }
        }

        /// <summary>
        /// ACD监听处理请求报文
        /// </summary>
        private async Task SIPACD(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            // 处理INVITE in-dialogue请求
            if (sipRequest.Method == SIPMethodsEnum.INVITE && sipRequest.Header.To.ToTag != null)
            {
                // 回复488 Not Acceptable Here响应
                SIPResponse notAcceptableResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotAcceptable, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(notAcceptableResponse);
            }
            // 处理SUBSCRIBE请求
            else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE)
            {
                // 回复405 Method Not Allowed响应
                SIPResponse methodNotAllowedResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(methodNotAllowedResponse);
            }
            // 处理OPTIONS和REGISTER请求
            else if (sipRequest.Method == SIPMethodsEnum.OPTIONS || sipRequest.Method == SIPMethodsEnum.REGISTER)
            {
                // 回复 200 OK
                SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(optionsResponse);
            }
            // 收到BYE请求
            else if (sipRequest.Method == SIPMethodsEnum.BYE)
            {
                // 回复 200 OK
                SIPResponse byeResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(byeResponse);

                // 删掉该呼叫
                string user = sipRequest.Header.From.FromURI.ToString().Split('@')[0].Split("sip:")[1];
                for (int i = 0; i < acdCallsCount; i++)
                {
                    if (acdCalls[i].uas != null && acdCalls[i].remoteUser == sipRequest.Header.From.FromURI.User)
                    {
                        acdCalls[i].uas.Hangup(true);
                        for (int j = i; j < acdCallsCount - 1; j++)
                        {
                            acdCalls[j] = acdCalls[j + 1];
                        }
                        acdCallsCount--;
                        OnACDListChanged();
                        break;
                    }
                }
            }
            // 收到INVITE请求
            else if (sipRequest.Method == SIPMethodsEnum.INVITE)
            {
                // 数量达到上限,拒绝该呼叫
                if (acdCallsCount == DEFAULT_MAX_ACD_CALLS)
                {
                    SIPResponse busyResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BusyHere, null);
                    if (sipTransport != null) await sipTransport.SendResponseAsync(busyResponse);
                    return;
                }

                // 数量未达到上限,分配空闲的ACDCall实例
                var uasTransaction = new UASInviteTransaction(sipTransport, sipRequest, null);
                int n = acdCallsCount;
                acdCallsCount++;
                acdCalls[n].uas = new SIPServerUserAgent(sipTransport, outboundProxy, uasTransaction, null);
                acdCalls[n].remoteUser = sipRequest.Header.From.FromURI.User;
                acdCalls[n].message = "";
                if (sipRequest.Body != null && sipRequest.Body.ToString().Contains("flag:"))
                {
                    // sipRequest.Body.ToString()中有多个Message=xxxxxxx;,提取每个Message=xxxxxxx;中的字符串并连接
                    string body = sipRequest.Body.ToString();
                    while (body.Contains("Message="))
                    {
                        acdCalls[n].message += body.Split("Message=")[1].Split(';')[0] + ";";
                        body = body.Substring(body.IndexOf("Message=") + 8);
                    }
                    acdCalls[n].localTag = sipRequest.Body.ToString().Split("LocalTag=")[1].Split(";")[0];
                }

                // 订阅呼叫状态事件
                acdCalls[n].uas.CallCancelled += (uasAgent, canelReq) =>
                {
                    string user = canelReq.Header.From.FromURI.ToString().Split('@')[0].Split("sip:")[1];
                    for (int i = 0; i < acdCallsCount; i++)
                    {
                        if (acdCalls[i].uas != null && acdCalls[i].remoteUser == user)
                        {
                            acdCalls[i].uas.Hangup(true);
                            for (int j = i; j < acdCallsCount - 1; j++)
                            {
                                acdCalls[j] = acdCalls[j + 1];
                            }
                            acdCallsCount--;
                            OnACDListChanged();
                            break;
                        }
                    }
                };

                // 回复 100 Trying响应
                SIPResponse tryingResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(tryingResponse);

                // 回复 180 Ringing响应
                SIPResponse ringingResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ringing, null);
                if (sipTransport != null) await sipTransport.SendResponseAsync(ringingResponse);

                OnACDListChanged();

                // 若无空闲坐席,退出等待,有则分配呼叫
                if (idleAgentsCount == 0) return;

                if (outboundProxy == null) return;

                // 检查呼叫号码是否是空闲坐席的LastCall,如果是,分配呼叫
                int agentnum = 0;
                for (int i = 0; i < idleAgentsCount; i++)
                {
                    if (idleAgents[i].lastCall1 == acdCalls[n].remoteUser || idleAgents[i].lastCall2 == acdCalls[n].remoteUser || idleAgents[i].lastCall3 == acdCalls[n].remoteUser)
                    {
                        agentnum = i;
                    }
                }

                // 呼叫转移
                string number = idleAgents[agentnum].number;
                SIPURI redirectURI = SIPURI.ParseSIPURI("sip:" + number + "@" + outboundProxy.Address);
                acdCalls[n].uas.Redirect(SIPResponseStatusCodesEnum.MovedTemporarily, redirectURI);

                ACDSession acdSession = new ACDSession();
                acdSession.agentNumber = idleAgents[agentnum].number;
                acdSession.remoteNumber = acdCalls[n].remoteUser;
                acdSession.message = acdCalls[n].message;
                acdSession.localTag = acdCalls[n].localTag;
                OnACDAllocateSuccess(acdSession);

                // 释放空闲坐席
                for (int i = agentnum; i < idleAgentsCount - 1; i++)
                {
                    idleAgents[i] = idleAgents[i + 1];
                }
                idleAgentsCount--;

                // 删掉该呼叫
                string user = sipRequest.Header.From.FromURI.ToString().Split('@')[0].Split("sip:")[1];
                for (int i = 0; i < acdCallsCount; i++)
                {
                    if (acdCalls[i].uas != null && acdCalls[i].remoteUser == sipRequest.Header.From.FromURI.User)
                    {
                        acdCalls[i].uas.Hangup(true);
                        for (int j = i; j < acdCallsCount - 1; j++)
                        {
                            acdCalls[j] = acdCalls[j + 1];
                        }
                        acdCallsCount--;
                        OnACDListChanged();
                        break;
                    }
                }
            }
        }
        #endregion  

        #region 委托/事件
        /// <summary>
        /// 接到消息,从Invite报文中提取到消息，注册成功, 注销成功,
        /// 开始呼叫（主动呼叫_Invite）,对方振铃（主动呼叫_Ringing）,
        /// 对方忙线(主动呼叫_Busy),对方拒绝（主动呼叫_Ringing到主动呼叫_Decline）,取消呼叫(主动呼叫_Cancel),
        /// 被呼叫振铃(被呼叫_Ringing),被呼叫拒绝(被呼叫_Decline),被呼叫取消(被呼叫_Cancel),被呼叫接受(被呼叫_Accept),
        /// 对方接通(主动呼叫_Talking),被呼叫接通(被呼叫_Talking),通话结束(End),
        /// 呼叫失败(主动呼叫_Failed)
        /// ACD列表变化(ACDListChanged)
        /// </summary>
        #region 收到MESSAGE报文
        public delegate void ReceiveMsgDelegate(SIPRequest message);
        public event ReceiveMsgDelegate? OnReceiveMsgEvent;
        private void OnReceiveMsg(SIPRequest message)
        {
            OnReceiveMsgEvent?.Invoke(message);
        }
        #endregion

        #region 从Invite报文中提取到消息
        public delegate void GetMsgFromInviteDelegate(string msg);
        public event GetMsgFromInviteDelegate? OnGetMsgFromInviteEvent;
        private void OnGetMsgFromInvite(string msg)
        {
            OnGetMsgFromInviteEvent?.Invoke(msg);
        }
        #endregion

        #region 注册成功
        public delegate void RegisterSuccessDelegate();
        public event RegisterSuccessDelegate? OnRegisterSuccessEvent;
        private void OnRegisterSuccess()
        {
            OnRegisterSuccessEvent?.Invoke();
        }
        #endregion

        #region 注销成功
        public delegate void UnRegisterSuccessDelegate();
        public event UnRegisterSuccessDelegate? OnUnRegisterSuccessEvent;
        private void OnUnRegisterSuccess()
        {
            OnUnRegisterSuccessEvent?.Invoke();
        }
        #endregion

        #region 开始呼叫
        public delegate void ActiveInviteDelegate();
        public event ActiveInviteDelegate? OnActiveInviteEvent;
        private void OnActiveInvite()
        {
            OnActiveInviteEvent?.Invoke();
        }
        #endregion

        #region 对方振铃
        public delegate void ActiveRingingDelegate();
        public event ActiveRingingDelegate? OnActiveRingingEvent;
        private void OnActiveRinging()
        {
            OnActiveRingingEvent?.Invoke();
        }
        #endregion

        #region 对方忙线
        public delegate void ActiveBusyDelegate();
        public event ActiveBusyDelegate? OnActiveBusyEvent;
        private void OnActiveBusy()
        {
            OnActiveBusyEvent?.Invoke();
        }
        #endregion

        #region 对方拒绝
        public delegate void ActiveDeclineDelegate();
        public event ActiveDeclineDelegate? OnActiveDeclineEvent;
        private void OnActiveDecline()
        {
            OnActiveDeclineEvent?.Invoke();
        }
        #endregion

        #region 取消呼叫
        public delegate void ActiveCancelDelegate();
        public event ActiveCancelDelegate? OnActiveCancelEvent;
        private void OnActiveCancel()
        {
            OnActiveCancelEvent?.Invoke();
        }
        #endregion

        #region 挂断
        public delegate void ByeDelegate();
        public event ByeDelegate? OnByeEvent;
        private void OnBye()
        {
            OnByeEvent?.Invoke();
        }
        #endregion

        #region 对方接通
        public delegate void ActiveTalkingDelegate();
        public event ActiveTalkingDelegate? OnActiveTalkingEvent;
        private void OnActiveTalking()
        {
            OnActiveTalkingEvent?.Invoke();
        }
        #endregion

        #region 被呼叫振铃
        public delegate void PassiveRingingDelegate();
        public event PassiveRingingDelegate? OnPassiveRingingEvent;
        private void OnPassiveRinging()
        {
            OnPassiveRingingEvent?.Invoke();
        }
        #endregion

        #region 被呼叫取消
        public delegate void PassiveCancelDelegate();
        public event PassiveCancelDelegate? OnPassiveCancelEvent;
        private void OnPassiveCancel()
        {
            OnPassiveCancelEvent?.Invoke();
        }
        #endregion

        #region 被呼叫拒绝
        public delegate void PassiveDeclineDelegate();
        public event PassiveDeclineDelegate? OnPassiveDeclineEvent;
        private void OnPassiveDecline()
        {
            OnPassiveDeclineEvent?.Invoke();
        }
        #endregion

        #region 被呼叫接受
        public delegate void PassiveAcceptDelegate();
        public event PassiveAcceptDelegate? OnPassiveAcceptEvent;
        private void OnPassiveAccept()
        {
            OnPassiveAcceptEvent?.Invoke();
        }
        #endregion

        #region 被呼叫接通
        public delegate void PassiveTalkingDelegate();
        public event PassiveTalkingDelegate? OnPassiveTalkingEvent;
        private void OnPassiveTalking()
        {
            OnPassiveTalkingEvent?.Invoke();
        }
        #endregion

        #region 通话结束
        public delegate void EndDelegate();
        public event EndDelegate? OnEndEvent;
        private void OnEnd()
        {
            OnEndEvent?.Invoke();
        }
        #endregion

        #region 呼叫失败
        public delegate void ActiveFailedDelegate();
        public event ActiveFailedDelegate? OnActiveFailedEvent;
        private void OnActiveFailed()
        {
            OnActiveFailedEvent?.Invoke();
        }
        #endregion

        #region ACD分配成功
        public delegate void ACDAllocateSuccessDelegate(ACDSession acdSession);
        public event ACDAllocateSuccessDelegate? OnACDAllocateSuccessEvent;
        private void OnACDAllocateSuccess(ACDSession acdSession)
        {
            OnACDAllocateSuccessEvent?.Invoke(acdSession);
        }
        #endregion

        #region ACD列表变化
        public delegate void ACDListChangedDelegate();
        public event ACDListChangedDelegate? OnACDListChangedEvent;
        private void OnACDListChanged()
        {
            OnACDListChangedEvent?.Invoke();
        }
        #endregion
        #endregion
    }
}
